package com.lancoo.ccas52.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lancoo.ccas52.aspect.LogAnnotation;
import com.lancoo.ccas52.entity.*;
import com.lancoo.ccas52.exception.BizException;
import com.lancoo.ccas52.pojo.common.PageInfo;
import com.lancoo.ccas52.pojo.vo.*;
import com.lancoo.ccas52.service.*;
import com.lancoo.ccas52.util.ExcelFormatUtil;
import com.lancoo.ccas52.util.ResponseObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Comparator;
import java.util.List;

/**
 * <p>
 * 教学任务相关模块
 * </p>
 *
 * @author quin.song
 * @since 2023-02-21
 */
@Api(tags = "教学任务")
@RestController
@RequestMapping("/api/v5.2.1/pc/teachTask")
public class TeachTaskController {

    @Resource
    private CourseService courseService;
    @Resource
    private TeachingClassService teachingClassService;
    @Resource
    private PlanTeachingService planTeachingService;
    @Resource
    private AssessmentMethodService assessmentMethodService;
    @Resource
    private SubClassService subClassService;

    @Resource
    private CourseWeekService courseWeekService;


    @ApiOperation("获取设置课程参数课程列表")
    @GetMapping(value = "/getSetCourseList")
    public ResponseObject<PageInfo<CoursePlanDto>> getCourseAndPlan(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                    @ApiParam(value = "修读性质 1主 2辅修", required = false) @RequestParam(required = false) Integer studyNature,
                                                                    @ApiParam(value = "课程类别id 传null全部", required = false) @RequestParam(required = false) String courseTypeId,
                                                                    @ApiParam(value = "课程性质 0全部 1必修  2选修", required = false) @RequestParam(required = false) Integer courseNature,
                                                                    @ApiParam(value = "专业性质，1:公共课，2:专业课", required = false) @RequestParam(required = false) Integer majorProp,
                                                                    @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                                    @ApiParam(value = "课程名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                                    @ApiParam(value = "1待设置 2已设置", required = false) @RequestParam(required = false) Integer state,
                                                                    @ApiParam(value = "1不可拆班 2可拆班", required = false) @RequestParam(required = false) Integer uniqueShiftSign,
                                                                    @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                    @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<CourseApplyDto> page = new Page<>(currentPage, pageSize);
        page.setOptimizeCountSql(false);
        return ResponseObject.ofSuccess(courseService.getCoursePlanAndCourseWeek(taskId, page, studyNature, courseTypeId, courseNature, majorProp, collegeId, keyWord, uniqueShiftSign, state));
    }

    @ApiOperation("设置课程参数")
    @PostMapping("/setCourseParams")
    @LogAnnotation(operationType = "2", operationContent = "设置课程参数")
    public ResponseObject<CourseWeek> setCourseWeek(@ApiParam(value = "课程参数实体类", required = true) @RequestBody WeekInput weekInput) {
        return ResponseObject.ofSuccess(courseService.setCourseWeek(weekInput));
    }

    @ApiOperation(value = "是否存在设置教室的教学班", notes = "true 存在 false 不存在")
    @GetMapping("/isExistRoom")
    public ResponseObject<Boolean> isExistRoom(@ApiParam(value = "课程id", required = true) @RequestParam Long courseId,
                                               @ApiParam(value = "修读性质：1主修2辅修", required = true) @RequestParam Integer studyNature,
                                               @ApiParam(value = "1讲授 2实验 3上机 4其他", required = true) @RequestParam Integer hourType) {
        return ResponseObject.ofSuccess(courseService.isExistRoom(courseId, studyNature,hourType));
    }

    @ApiOperation("获取课程参数")
    @PostMapping("/getCourseParams")
    @LogAnnotation(operationType = "2", operationContent = "设置课程参数")
    public ResponseObject<List<CourseWeek>> getCourseParams(@ApiParam(value = "课程id", required = true) @RequestParam(required = true) Long courseId,
                                                            @ApiParam(value = "修读性质 1主 2辅修", required = true) @RequestParam(required = true) Integer studyNature) {
        List<CourseWeek> list = courseWeekService.lambdaQuery().eq(CourseWeek::getCourseId, courseId).eq(CourseWeek::getStudyNature, studyNature).list();
        list.sort(Comparator.comparingInt(CourseWeek::getHourType));
        return ResponseObject.ofSuccess(list);
    }

    @ApiOperation("获取下次设置单双周值")
    @GetMapping("/getCourseNextOddEven")
    public ResponseObject<Integer> getNextOddEven(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId) {
        return ResponseObject.ofSuccess(courseService.oddEvenWeekStatistics(taskId));
    }

    @ApiOperation("获取设置课程教学班列表")
    @GetMapping(value = "/getSetCourseClassList")
    public ResponseObject<PageInfo<CoursePlanDto>> getSetCourseClassList(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                         @ApiParam(value = "修读性质 1主 2辅修", required = false) @RequestParam(required = false) Integer studyNature,
                                                                         @ApiParam(value = "课程类别id 传null全部", required = false) @RequestParam(required = false) String courseTypeId,
                                                                         @ApiParam(value = "课程性质 0全部 1必修  2选修", required = false) @RequestParam(required = false) Integer courseNature,
                                                                         @ApiParam(value = "专业性质，1:公共课，2:专业课", required = false) @RequestParam(required = false) Integer majorProp,
                                                                         @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                                         @ApiParam(value = "课程名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                                         @ApiParam(value = "1待设置 2已设置", required = false) @RequestParam(required = false) Integer state,
                                                                         @ApiParam(value = "0无需选课 1在线选课;2:分级教学 3:预选教学班 4:全部", required = true) @RequestParam Integer teachingClassType,
                                                                         @ApiParam(value = "1不可拆班 2可拆班", required = false) @RequestParam(required = false) Integer uniqueShiftSign,
                                                                         @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                         @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<CoursePlanDto> page = new Page<>(currentPage, pageSize);
        page.setOptimizeCountSql(false);
        return ResponseObject.ofSuccess(courseService.getCoursePlanAndTeachingClass(taskId, page, studyNature, courseTypeId, courseNature, majorProp, collegeId, keyWord, state, teachingClassType, uniqueShiftSign));
    }

    @ApiOperation("设置教学班参数")
    @PostMapping("/setTeachingClassWeek")
    @LogAnnotation(operationType = "2", operationContent = "设置教学班参数")
    public ResponseObject<TeachingClassWeek> setTeachingClassWeek(@ApiParam(value = "教学班周次实体类", required = true) @RequestBody TeachingClassWeek teachingClassWeek) {
        return ResponseObject.ofSuccess(courseService.setTeachingClassWeek(teachingClassWeek));
    }

    @ApiOperation("获取设置环节参数课程列表")
    @GetMapping(value = "/getSetLinkParamsList")
    public ResponseObject<PageInfo<SegmentPlanDto>> getSetSegmentList(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                      @ApiParam(value = "修读性质 1主 2辅修", required = false) @RequestParam(required = false) Integer studyNature,
                                                                      @ApiParam(value = "环节类别id 传null全部", required = false) @RequestParam(required = false) String segmentTypeId,
                                                                      @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                                      @ApiParam(value = "环节名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                                      @ApiParam(value = "1待设置 2已设置", required = false) @RequestParam(required = false) Integer state,
                                                                      @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                                      @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        Page<SegmentPlanDto> page = new Page<>(currentPage, pageSize);
        page.setOptimizeCountSql(false);
        return ResponseObject.ofSuccess(courseService.getSegmentPlanAndTeachingClass(taskId, page, studyNature, segmentTypeId, collegeId, keyWord, state));
    }

    @ApiOperation("设置环节参数")
    @PostMapping("/setSegmentParams")
    @LogAnnotation(operationType = "2", operationContent = "设置环节参数")
    public ResponseObject<SegmentWeek> setSegmentWeek(@ApiParam(value = "教学班实体类", required = true) @RequestBody SegmentWeek segmentWeek) {
        return ResponseObject.ofSuccess(courseService.setSegmentWeek(segmentWeek));
    }

    @ApiOperation("设置课程考核方式")
    @PostMapping("/setAssessment")
    @LogAnnotation(operationType = "2", operationContent = "设置课程考核方式")
    public ResponseObject<CourseSetting> setAssessment(@ApiParam(value = "修改相关参数", required = true) @RequestBody CourseSetting courseSetting) {
        return ResponseObject.ofSuccess(planTeachingService.setAssessment(courseSetting));
    }

    @ApiOperation("设置环节考核方式")
    @PostMapping("/setSegmentAssessment")
    @LogAnnotation(operationType = "2", operationContent = "设置环节考核方式")
    public ResponseObject<SegmentSetting> setSegmentAssessment(@ApiParam(value = "修改相关参数", required = true) @RequestBody SegmentSetting segmentSetting) {
        return ResponseObject.ofSuccess(planTeachingService.setSegmentAssessment(segmentSetting));
    }


    @ApiOperation("教学任务统计")
    @GetMapping(value = "/teachingTaskStatistics")
    public ResponseObject<TeachingTaskStatistics> teachingTaskStatistics(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId) {
        return ResponseObject.ofSuccess(courseService.teachingTaskStatistics(taskId));
    }

    @ApiOperation("添加拆班班级")
    @PostMapping("/addClassSub")
    public ResponseObject<List<SubClass>> addClassSub(@ApiParam(value = "拆班行政班实体类 ", required = true) @RequestBody List<SubClass> subClasses) {
        return ResponseObject.ofSuccess(subClassService.addSubClass(subClasses));
    }

    @ApiOperation("批量删除拆班班级")
    @DeleteMapping("/removeSubClass")
    public ResponseObject<Boolean> removeSubClass(@ApiParam(value = "id", required = true) @RequestBody List<Long> ids) {
        return ResponseObject.ofSuccess(subClassService.removeSubClass(ids));
    }

    @ApiOperation("获取拆班列表")
    @GetMapping(value = "/getClassSub")
    public ResponseObject<PageInfo<SubClass>> getClassSub(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                          @ApiParam(value = "1单班级  2多班级", required = false) @RequestParam(required = false) Integer type,
                                                          @ApiParam(value = "年级id", required = false) @RequestParam(required = false) String gradeId,
                                                          @ApiParam(value = "行政班名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                          @ApiParam(value = "页码", required = true) @RequestParam Integer currentPage,
                                                          @ApiParam(value = "页容", required = true) @RequestParam Integer pageSize) {
        return ResponseObject.ofSuccess(subClassService.getClassSub(taskId, type, gradeId, keyWord, currentPage, pageSize));
    }

    @ApiOperation("获取拆班课程")
    @GetMapping(value = "/getShiftCourse")
    public ResponseObject<List<SubCourseVo>> getShiftCourse(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                            @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                            @ApiParam(value = "专业性质，1:公共课，2:专业课", required = false) @RequestParam(required = false) Integer majorProp,
                                                            @ApiParam(value = "行政班id", required = false) @RequestParam(required = false) String classId) {
        return ResponseObject.ofSuccess(subClassService.getSubCourse(taskId, collegeId, majorProp, classId));
    }

    @ApiOperation("获取拆班班级")
    @GetMapping(value = "/getClass")
    public ResponseObject<List<ClassDto>> getClass(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                   @ApiParam(value = "行政班名模糊查询", required = false) @RequestParam(required = false) String keyWord,
                                                   @ApiParam(value = "基础课程id", required = false) @RequestParam(required = false) String baseCourseId) {
        return ResponseObject.ofSuccess(subClassService.getSubClass(taskId, keyWord, baseCourseId));
    }

    @ApiOperation("获取拆班教学班")
    @GetMapping(value = "/getSubTeachingClass")
    public ResponseObject<List<TeachingClass>> getSubTeachingClass(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                                   @ApiParam(value = "分班唯一标识", required = true) @RequestParam(required = true) String uniqueShiftSign) {
        return ResponseObject.ofSuccess(teachingClassService.getByUniqueShiftSign(uniqueShiftSign));
    }

    @ApiOperation("校验发布教学任务数据")
    @PutMapping(value = "/checkPublishTeachTask")
    public ResponseObject<List<TeachingClass>> checkPublishTeachTask(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId) {
        return ResponseObject.ofSuccess(teachingClassService.checkPublishTeachTask(taskId));
    }

    @ApiOperation("发布教学任务")
    @PutMapping(value = "/publishTeachTask")
    @LogAnnotation(operationType = "8", operationContent = "发布教学任务")
    public ResponseObject<Boolean> publishPlan(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId) {
        return ResponseObject.ofSuccess(teachingClassService.publishTeachTask(taskId));
    }

    @ApiOperation("导出课程教学计划")
    @GetMapping(value = "/excel/course")
    @LogAnnotation(operationType = "14", operationContent = "导出课程教学计划")
    public ResponseObject<Object> teachingTaskExcel(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                    @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                    @ApiParam(value = "开课单位名字 ", required = false) @RequestParam(required = false) String collegeName,
                                                    @ApiParam(value = "课程类别id 传null全部", required = false) @RequestParam(required = false) String courseTypeId,
                                                    @ApiParam(value = "课程类别名字", required = false) @RequestParam(required = false) String courseType,
                                                    @ApiParam(value = "课程性质 1必修  2选修", required = false) @RequestParam(required = false) Integer courseNature,
                                                    @ApiParam(value = "修读性质 1主 2辅修", required = false) @RequestParam(required = false) Integer studyNature) {
        return ResponseObject.ofSuccess(teachingClassService.teachTaskToExcel(taskId, collegeId, collegeName, courseTypeId, courseType, courseNature, studyNature));
    }

    @ApiOperation("导出环节教学计划")
    @GetMapping(value = "/excel/segment")
    @LogAnnotation(operationType = "14", operationContent = "导出环节教学计划")
    public ResponseObject<Object> teachingTaskSegmentExcel(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                           @ApiParam(value = "学院id ", required = false) @RequestParam(required = false) String collegeId,
                                                           @ApiParam(value = "开课单位名字 ", required = false) @RequestParam(required = false) String collegeName,
                                                           @ApiParam(value = "环节类别id 传null全部", required = false) @RequestParam(required = false) String courseTypeId,
                                                           @ApiParam(value = "环节类别名字", required = false) @RequestParam(required = false) String courseType,
                                                           @ApiParam(value = "修读性质 1主 2辅修", required = false) @RequestParam(required = false) Integer studyNature) {
        return ResponseObject.ofSuccess(teachingClassService.segmentToExcel(taskId, collegeId, collegeName, courseTypeId, courseType, studyNature));
    }

    @ApiOperation("批量导入教学班-分级")
    @PostMapping("/bulk/teachingClass")
    @LogAnnotation(operationType = "13", operationContent = "批量导入教学班-分级")
    public ResponseObject<Boolean> excelToTeachingClass(@ApiParam(value = "教学计划参数", required = true) ImportTeachingClass importTeachingClass,
                                                        @ApiParam("file") @RequestPart("file") MultipartFile file) {
        //fileName 文件名
        String fileName = file.getOriginalFilename();
        if (StrUtil.isBlank(fileName) || (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx"))) {
            throw new BizException(5, "文件格式不正确");
        }
        return ResponseObject.ofSuccess(teachingClassService.excelToTeachingClass(importTeachingClass, file));
    }

    @ApiOperation("导出课程教学计划-鮀滨版本支持导出即导入")
    @GetMapping(value = "/excel/courseDetail")
    public ResponseObject<Object> teachingTaskExcel(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                    HttpServletRequest request,
                                                    HttpServletResponse response) {
        ServletOutputStream out = ExcelFormatUtil.pretreatment(request, response, "教学任务模板.xlsx");
        teachingClassService.teachTaskToExcel(taskId, out);
        return ResponseObject.ofSuccess();
    }

    @Deprecated
    @ApiOperation("导入课程教学计划")
    @PostMapping(value = "/bulk/teachingClassTask")
    public ResponseObject<FileImportInfo> excelToTeachingTask(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                              @ApiParam("file") @RequestPart("file") MultipartFile file) {
        return ResponseObject.ofSuccess(teachingClassService.excelToTeachingTask(taskId, file));
    }
    @ApiOperation("导入全部课程教学计划")
    @PostMapping(value = "/bulk/excelToTeachingTaskAll")
    public ResponseObject<FileImportInfo> excelToTeachingTaskAll(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                              @ApiParam("file") @RequestPart("file") MultipartFile file) {
        return ResponseObject.ofSuccess(teachingClassService.excelToTeachingTaskAll(taskId, file));
    }

    @ApiOperation("导入分班教学班")
    @PostMapping(value = "/bulk/excelToSubClass")
    public ResponseObject<FileImportInfo> excelToSubClass(@ApiParam(value = "任务流程id", required = true) @RequestHeader Integer taskId,
                                                          @ApiParam("file") @RequestPart("file") MultipartFile file) {
        return ResponseObject.ofSuccess(teachingClassService.excelToSubClass(taskId, file));
    }

    @ApiOperation("获取考核方式")
    @GetMapping(value = "/getAssessmentMethod")
    public ResponseObject<List<AssessmentMethod>> getAssessmentMethod(@ApiParam(value = "学校id", required = true) @RequestParam String schoolId,
                                                                      @ApiParam(value = "1课程  2环节", required = true) @RequestParam Integer flag) {
        List<AssessmentMethod> list = assessmentMethodService.lambdaQuery().eq(AssessmentMethod::getFlag, flag).eq(AssessmentMethod::getSchoolId, schoolId).list();
        //插入为空则插入默认值
        if (list.size() == 0) {
            list.add(new AssessmentMethod().setFlag(flag).setSchoolId(schoolId).setAssessmentName("考试"));
            list.add(new AssessmentMethod().setFlag(flag).setSchoolId(schoolId).setAssessmentName("考查"));
            assessmentMethodService.saveBatch(list);
        }
        list.forEach(o -> {
            if ("考试".equals(o.getAssessmentName())){
                o.setSort(0);
            }else if ("考查".equals(o.getAssessmentName())){
                o.setSort(1);
            }else {
                o.setSort(10);
            }

        });
        list.sort(Comparator.comparing(AssessmentMethod::getSort));
        return ResponseObject.ofSuccess(list);
    }

    @ApiOperation("添加考核方式")
    @PostMapping(value = "/addAssessmentMethod")
    public ResponseObject<AssessmentMethod> addAssessmentMethod(@ApiParam(value = "考核方式实体类", required = true) @RequestBody AssessmentMethod assessmentMethod) {
        assessmentMethodService.save(assessmentMethod);
        return ResponseObject.ofSuccess(assessmentMethod);
    }

    @ApiOperation("删除考核方式")
    @DeleteMapping(value = "/removeAssessmentMethod/{assessmentId}")
    public ResponseObject<Boolean> removeAssessmentMethod(@ApiParam(value = "考核方式Id", required = true) @PathVariable String assessmentId) {
        return ResponseObject.ofSuccess(assessmentMethodService.removeById(assessmentId));
    }


}
